package bgpemulation;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public abstract class CIDRMap<T extends Serializable> implements Serializable{
	
	private static final long serialVersionUID = 1L;
	protected Map<Integer, Map<CIDRPrefix, T>> prefixes = new HashMap<Integer, Map<CIDRPrefix, T>>();
	
	public CIDRMap(){
		for(int i = 1; i<=CIDRPrefix.MAX_MASK_SIZE; i++){
			prefixes.put(new Integer(i), new TreeMap<CIDRPrefix, T>());
		}
	}
	
	public T get(CIDRPrefix prefix){
		for(int i = CIDRPrefix.MAX_MASK_SIZE; i>0; i--){
			T value = prefixes.get(i).get(prefix);
			if(value!=null){
				return value;
			}
		}
		return null;
	}

	public boolean put(CIDRPrefix key, String value){
		Map<CIDRPrefix, T> prefixesOfCorrectLength = prefixes.get(key.getPrefixLength());
		T oldValue = prefixesOfCorrectLength.get(key);
		if(oldValue==null){
			prefixesOfCorrectLength.put(key, makeEntry(value));
			return true;
		} else{
			return updateValue(oldValue, value);
		}
	}
	
	public void delete(CIDRPrefix p){
		CIDRPrefix k1 = new CIDRPrefix("138.172.0.0/14");
		prefixes.get(p.getPrefixLength()).remove(p);
	}

	public void print(){
		for(int i = 1; i<CIDRPrefix.MAX_MASK_SIZE; i++){
			print(prefixes.get(i));
		}
	}
	
	private void print(Map<CIDRPrefix, T> map) {
		for(CIDRPrefix prefix : map.keySet()){
			System.out.println(prefix + ":");
			print(map.get(prefix));
		}
	}

	public abstract void print(T t);
	public abstract T makeEntry(String value);
	public abstract boolean updateValue(T oldValue, String value);
	public abstract boolean remove(CIDRPrefix p, String value);

}
